package switchviz.core.view;

import java.awt.Dimension;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import switchviz.core.ResourceManager;
import switchviz.graphic.gauge.GaugeNodeModel;
import switchviz.gui.component.IXMLFilter;
import switchviz.gui.component.XMLTree;
import switchviz.gui.component.XMLTreeNode;
import switchviz.util.FileOperations;

public class ViewTree extends XMLTree
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -8444983822933069176L;
	public static final String VIEWNODE = "view";
	public static final String VIEWNAMENODE = "name";
	public static final String VIEWBGCOLOR = "color";
	public static final String VIEWDESCRIPTIONNODE = "description";
	public static final String GAUGENODE = "gauge";
	public static final String GAUGEATTNAME = "name";
	public static final String GAUGEATTTYPE = "type";
	
	private static FilenameFilter _filter = new FilenameFilter() 
	{
        public boolean accept(File dir, String name) 
        {
            return name.endsWith(".xml");
        }
    };
    
	public static ViewDataModel createNewView()
	{
		ViewDataModel datamodel = new ViewDataModel();
		File file = FileOperations.getUniqueXMLInDir(ResourceManager.getInstance().getViewFolder(), datamodel.getName());
		datamodel.setFile(file);
		
		Document doc = new Document(createNewViewNodes(datamodel));
		try 
		{
			FileOperations.saveXML(file, doc);
			if (logger.isInfoEnabled())
				logger.info("View Configuration " + file.getAbsolutePath() + " successfully created.");
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
			logger.warn("Problems occured creating the View Configuration: " + file.getAbsolutePath());
		}
		return datamodel;
	}
	
	public static Element createNewViewNodes(ViewDataModel datamodel)
	{
		Element root = new Element(VIEWNODE);
		root.addContent((new Element(VIEWNAMENODE)).setText(datamodel.getName()));
		root.addContent((new Element(VIEWDESCRIPTIONNODE)).setText(datamodel.getDescription()));
		root.addContent((new Element(VIEWBGCOLOR)).setText(datamodel.getBGColor()[0] + ";" + datamodel.getBGColor()[1] + ";" + datamodel.getBGColor()[2]));
		return root;
	}
	
	public static File getFirstConfiguration()
	{
		File file = ResourceManager.getInstance().getViewFolder();
		if (file.listFiles(_filter).length > 0)
			return file.listFiles(_filter)[0];
		else
			return createNewView().getFile();
	}

	public static List<ViewDataModel> getViewList() throws JDOMException, IOException
	{
		ArrayList<ViewDataModel> viewlist = new ArrayList<ViewDataModel>();
		
		File[] views = ResourceManager.getInstance().getViewFolder().listFiles(_filter);
		for(File viewfile : views)
			viewlist.add(getViewFromFile(viewfile));
		
		return viewlist;
	}
	
	public void reNameAndSave(String newname)
	{
		if(this._xmlfile.exists())
			_xmlfile.delete();
			
		this.saveXMLAs(FileOperations.getUniqueXMLInDir(ResourceManager.getInstance().getViewFolder(), newname));
	}
	
	public static ViewDataModel getViewFromFile(File viewfile) throws JDOMException, IOException
	{
		SAXBuilder parser = new SAXBuilder();
		Document doc = parser.build(viewfile);
		Element root = doc.getRootElement();
		ViewDataModel datamodel = new ViewDataModel();
		if(root.getChild(VIEWNAMENODE) != null)
			datamodel.setName(root.getChildText(VIEWNAMENODE));
		if(root.getChild(VIEWDESCRIPTIONNODE) != null)
			datamodel.setDescription(root.getChildText(VIEWDESCRIPTIONNODE));
		if(root.getChild(VIEWBGCOLOR) != null)
			datamodel.setBGColor(getColorCode(root.getChildText(VIEWBGCOLOR)));
		datamodel.setFile(viewfile);
		datamodel.setGaugeList(getGaugeList(root));
		return datamodel;
	}
	
	
	public ViewTree(File xmlfile, IXMLFilter xmlfilter) throws JDOMException, IOException 
	{
		super(xmlfile, xmlfilter);
		this.setPreferredSize(new Dimension(400, 400));
		this.getTree().setRootVisible(false);
		this.setLeafNodeIcon(ResourceManager.getInstance().getImageIconGauge());
	}
	
	public void addNode(String nodename, String value)
	{
		Element el = ((XMLTreeNode)_root).getElement().getChild(nodename);
		if(el != null)
			el.setText(value);
		else
			((XMLTreeNode)_root).getElement().setContent((new Element(nodename)).setText(value));
	}
	
	public void copyNode()
	{
		Element gaugelist = ((XMLTreeNode)_root).getElement();
		Element selectedElement = ((XMLTreeNode)this.getTree().getLastSelectedPathComponent()).getElement();
		if(selectedElement != null && selectedElement.getName().equals(ViewTree.GAUGENODE))
		{
			gaugelist.addContent((Element)selectedElement.clone());
		}
	}
	
	public void updateView(ViewDataModel dm)
	{
		addNode(VIEWNAMENODE, dm.getName());
		addNode(VIEWDESCRIPTIONNODE, dm.getDescription());
		addNode(VIEWBGCOLOR, dm.getBGColor()[0] + ";" + dm.getBGColor()[1] + ";" + dm.getBGColor()[2]);
	}
	
	public void updateActElement(Element actelement)
	{
		if(actelement == null) 
		{
			System.out.println("actelement isch null");
			return;
		}
    	Element selectedElement = ((XMLTreeNode)getTree().getLastSelectedPathComponent()).getElement();
    	if (selectedElement.getName().equals(ViewTree.GAUGENODE))
    	{
    		//selectedElement = _actgauge.getElement();
    		Element parent = selectedElement.getParentElement();
    		int childindex = parent.indexOf(selectedElement);
    		//selectedElement.removeContent();
    		parent.removeContent(selectedElement);
    		parent.addContent(childindex, (Element)actelement);
    	}
	}
	
	public Element newGaugeListElement(String gaugetype, String gaugename)
	{
		Element gaugelist = ((XMLTreeNode)_root).getElement();
		Element newgauge = new Element(GAUGENODE).setAttribute(GAUGEATTNAME, gaugename);
		newgauge.setAttribute(GAUGEATTTYPE, gaugetype);
		gaugelist.addContent(newgauge);
		return newgauge;
	}
	
	public void removeNode()
	{
		Element selectedElement = ((XMLTreeNode)getTree().getLastSelectedPathComponent()).getElement();
    	if (selectedElement.getName().equals(ViewTree.GAUGENODE))
    	{
    		super.removeNode();
    	}
	}
	
	private static float[] getColorCode(String colorcode)
	{
		float[] color = {0.0f, 0.0f, 0.0f};
		StringTokenizer tokenizer = new StringTokenizer(colorcode, ";", false);
		int i = 0;
		while(tokenizer.hasMoreTokens())
		{
			if(i == 3) break;
			color[i] = Float.valueOf(tokenizer.nextToken());
			++i;
		}
		return color;
	}
	
	private static List<GaugeNodeModel> getGaugeList(Element root)
	{
		List<GaugeNodeModel> gaugelist = new ArrayList<GaugeNodeModel>();
		if(root != null) 
		{	
			Iterator<?> it = root.getChildren(GAUGENODE).iterator();
			while(it.hasNext())
			{
				Element gaugeconf = (Element)it.next();
				if(gaugeconf.getAttribute(GAUGEATTTYPE) != null)
					gaugelist.add(new GaugeNodeModel(gaugeconf.getAttributeValue(GAUGEATTNAME), gaugeconf.getAttributeValue(GAUGEATTTYPE), gaugeconf));
			}
		}
		return gaugelist;
	}
}
